package main

import "reflect"

type INT int

type A0 struct {
	a int
}

type B0 struct {
	b string
}

type Ita interface {
	String() string
}

func (b B0) String() string {
	return b.b
}

func main() {
	/*
		对于 reflect.TypeOf(a)：
			传进去的实参 a 有两种类型：接口类型、具体类型
				A:如果 a 是具体类型变量：
					函数返回的是具体的类型信息

				B:如果 a 是一个接口变量，则函数的返回结果又分为两种情况：
					A:如果 a 绑定了具体类型实例，返回接口的动态类型，也就是 a 绑定的具体类型实例的信息
					B:如果 a 没有绑定具体类型实例，返回接口自身的静态类型信息
	*/
	var a INT = 12
	var b int = 14

	//实参是具体类型，reflect.TypeOf 返回其静态类型
	ta := reflect.TypeOf(a)
	tb := reflect.TypeOf(b)

	//INT 和 int 是两个类型，二者不相等
	if ta == tb {
		println("ta == tb")
	} else {
		println("ta != tb")
	}

	println(ta.Name()) //INT
	println(tb.Name()) //int

	//底层基础类型
	println(ta.Kind().String()) //int
	println(tb.Kind().String()) //int

	s1 := A0{1}
	s2 := B0{"喜羊羊"}

	//实参是具体类型，reflect.TypeOf() 返回的是其静态类型
	println(reflect.TypeOf(s1).Name()) //A0
	println(reflect.TypeOf(s2).Name()) //B0

	//Type 的 Kind() 方法返回的是基础类型，类型 A0 和 B0 的底层基础类型都是 struct
	println(reflect.TypeOf(s1).Kind().String())
	println(reflect.TypeOf(s2).Kind().String())

	ita := new(Ita)
	var itb Ita = s2

	//实参是未绑定具体变量的接口类型， reflect.TypeOf 返回的是接口类型本身
	//也就是接口的静态变量
	println(reflect.TypeOf(ita).Elem().Name())          //Ita
	println(reflect.TypeOf(ita).Elem().Kind().String()) //interface

	//实参是绑定了具体变量的接口类型，reflect.TypeOf 返回的是绑定的具体类型
	//也就是接口的动态类型
	println(reflect.TypeOf(itb).Name())          //B0
	println(reflect.TypeOf(itb).Kind().String()) //struct
}
